
<script lang="ts">
// 鼠标事件
const mouseEvents = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseup', 'mouseover', 'mouseout', 'globalout', 'contextmenu']
//  zrender事件的鼠标事件
const zrMouseEvents = mouseEvents.map((item) => ('zr' + item.charAt(0).toUpperCase() + item.slice(1)));
// 所有鼠标事件
const allMouseEvents = [...mouseEvents, ...zrMouseEvents];
</script>

<script setup lang='ts'>
import * as echarts from 'echarts';
// import 'echarts-extension-amap';
import { nextTick } from 'vue';
import { onMounted, onUnmounted, ref, watch } from 'vue';

const props = defineProps({
    width: {
        type: String,
        default: '100%'
    },
    height: {
        type: String,
        default: '400px'
    },
    // 是否开启监听图表容器的大小并改变图表大小
    resize: {
        type: Boolean,
        default: true
    },
    // 是否开启暗色模式
    dark: {
        type: Boolean,
        default: false
    },
    echartsOption: {
        type: Object,
        default: () => ({})
    }
})

const emit = defineEmits(allMouseEvents);
const el = ref(null);
let myChart: any;

// 防抖函数
function debounce(func: Function, duration: number = 500) {
    let timeoutID: number;
    return function (...args: any) {
        // console.log(args);
        clearTimeout(timeoutID)
        timeoutID = setTimeout(() => {
            func.apply(this, args);
        }, duration);
    }
}

let d_resize = debounce(() => {
    myChart.resize();
}, 500);

function openResize() {
    // 监听页面的resize事件，重新改变图表大小
    window.addEventListener('resize', d_resize);
}
// 初始化echarts
function echartsInit() {
    console.log("echartsInit::")
    myChart = echarts.init(el.value, props.dark ? 'dark' : undefined);
}
// 设置option
function echartsSetOption(option: Object) {

    if(!option) return
    myChart.setOption(option);
}
// 摧毁echarts
function echartsDestroy() {
    myChart && myChart.dispose();
}
// 监听所有鼠标事件
function echartsBindEvents() {
    mouseEvents.forEach((eventName) => {
        // 监听图表的鼠标事件,抛出事件的params
        myChart.on(eventName, function (eventParams: Object) {
            emit(eventName, eventParams);
        });
        //  监听图表的空白区，即zrender事件
        myChart.getZr().on(eventName, function (event: any) {
            // 没有 target 意味着鼠标/指针不在任何一个图形元素上，它是从“空白处”触发的。
            if (!event.target) {
                const zrMouseEventName = 'zr' + eventName.charAt(0).toUpperCase() + eventName.slice(1);
                emit(zrMouseEventName, event);
            }
        });
    });
}
// 进行一系列操作，包括创建echarts实例，绑定事件，重新绘制等
function echartsRun() {
    // 初始化一个echarts实例
    echartsInit();
    // 绘制图表
    echartsSetOption(props.echartsOption);
    // 监听图表容器的大小并改变图表大小
    props.resize && openResize();
    // 监听所以鼠标事件
    echartsBindEvents();
}
// 监听echartsOption，重新绘画
watch(props.echartsOption, () => {
    echartsSetOption(props.echartsOption);
},
{deep: true});
// 监听dark，重新初始化
watch(() => props.dark, () => {
    echartsDestroy();
    echartsRun();
});
onMounted(() => {
    echartsRun();
});
onUnmounted(() => {
    // 取消监听图表容器的大小，改变图表大小事件
    props.resize && window.removeEventListener('resize', d_resize);
    echartsDestroy();
});
</script>

<template>
    <div ref="el" :style="{ width: width, height: height }"></div>
</template>

